{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "MMDAutoTraceLip1.00.04.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vEkCwPsnYcEu"
      },
      "source": [
        "# colab版MMD自動トレースv2（リップ版）へようこそ！(実行編)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lqSBUG5dYgoU"
      },
      "source": [
        "# 始めに\n",
        "\n",
        "このツールの稼働状況やメンテナンス情報はTwitter（[@miu200521358](https://twitter.com/miu200521358)）にて行っています。\n",
        "\n",
        "エラーになる、起動しない、などの場合、まずは現在の配布状況をご確認ください。\n",
        "\n",
        "リプやDM等でのお問い合わせも受け付けています。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iF8KZvMQ1D8O"
      },
      "source": [
        "# 目次\n",
        "\n",
        "このノートブックでは、MMD自動トレースの準備と実行を行います。\n",
        "\n",
        "ノートブックの使い方にはクセがあるので、「[準備編](https://colab.research.google.com/github/miu200521358/motion_trace_colab/blob/master/AutoTraceIntroduction.ipynb)」で使い方に慣れてください。\n",
        "\n",
        "画面左上の「＝」（実際は三本線）をクリックして下さい。目次が開きます。（既に開いている場合は次へ進んでください）\n",
        "\n",
        "![目次](https://drive.google.com/uc?export=view&id=1HGk4sJmcPtMbMwcJOvE3aU1GjvKinwA_)\n",
        "\n",
        "Googleドライブの直下に`autotrace`フォルダを作成してください。\n",
        "\n",
        "（準備編で既に作られている場合は再作成不要です）\n",
        "\n",
        "ノートブックを上から順に確認し、以下手順をひとつずつ実行してください。\n",
        "\n",
        "実行が必要なセルには番号を振ってあります。①から順番に実行してください。\n",
        "\n",
        "\n",
        "- **「①　データ連携」**\n",
        "  - Googleドライブと連携します\n",
        "  - 連携のやり方は、導入編をご確認ください\n",
        "- **「②　環境設定」**\n",
        "  - ランタイムがGPUに変更できたことを確認します\n",
        "    - 変更のやり方は、導入編をご確認ください\n",
        "  - Tensorflowのバージョンを1.xに変更します\n",
        "  - 効果音を[効果音ラボ](https://soundeffect-lab.info/)様よりダウンロードします\n",
        "   - 準備や実際のトレース処理等、長い処理時に鳴らします\n",
        "   - 不要の場合は、ブラウザの音量をミュートにしてください\n",
        "- **「③　準備」**\n",
        "    - MMD自動トレースに必要なコードをcolab上に構築します。\n",
        "    - 大体10分くらいかかります。\n",
        "- **「④　音声配置」**\n",
        "    - MMD自動トレースの対象となる音声データを配置します。\n",
        "- **「⑤　MMD自動トレース実行」**\n",
        "    - MMD自動トレースを実行します。\n",
        "\n",
        "---\n",
        "\n",
        "※作業中に下記のような警告が出ることがありますが、そのまま進めていただいて問題ありません\n",
        "\n",
        "　（GPUを使うのは主に音声分離などの一部分ですので、その他のセルを作業中に出る可能性があります。）\n",
        "\n",
        "![警告](https://drive.google.com/uc?export=view&id=1mRW32urnPQ4LS4xrLEoPdp_XCqlq1HUF)\n",
        "\n",
        "---\n",
        "\n",
        "※下記のようなエラーが出た場合、環境が既に破棄されています。\n",
        "\n",
        "目次からセル①に戻って、すべて実行し直してください。\n",
        "\n",
        "![Googleドライブ連携](https://drive.google.com/uc?export=view&id=1Tsjzs2QAECPMfUTaTh7PYX2cMEypEIF2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ceAv9Mdy1aXA"
      },
      "source": [
        "# MMD自動トレース（リップ）実行"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5MglDflC1fIk"
      },
      "source": [
        "## ①　データ連携\n",
        "\n",
        "Googleドライブの `autotrace` フォルダと連携します。\n",
        "\n",
        "下の【①】のセルを実行して、連携許可のキーを入力欄に「Ctrl+V」で貼り付けて下さい。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jDfgN-TX1kJs",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル①】　Googleドライブとの連携\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "exec_dict = {}\n",
        "exec_dict['1'] = True\n",
        "\n",
        "from google.colab import drive\n",
        "import os\n",
        "\n",
        "# Googleドライブマウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "# 起点ディレクトリ\n",
        "base_path = \"/gdrive/My Drive/autotrace\"\n",
        "\n",
        "if os.path.exists(base_path):\n",
        "    ! echo \"autotraceフォルダの中身 -----------\"\n",
        "    ! ls -l \"$base_path\"\n",
        "    ! echo \"--------------------\"\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　autotraceフォルダとの連携が成功しました。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    exec_dict['1'] = True\n",
        "else:\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　autotraceフォルダがGoogleドライブの直下に見つかりませんでした。\")\n",
        "    print(\"■　準備編から実行し直してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "01zd2g7L1oKU"
      },
      "source": [
        "**【OK】**\n",
        "\n",
        "下記のように、「autotrace」フォルダの中身が表示されていたら成功です。\n",
        "\n",
        "![Googleドライブ連携](https://drive.google.com/uc?export=view&id=19OhLvcyP-CN90KWDmkmBuSRR3BpO5GzV)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tQJNHukh1unm"
      },
      "source": [
        "## **②　環境設定**"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_wXc3kLV1xKW"
      },
      "source": [
        "ヘッダの \"ランタイム\"　＞　\"ランタイムのタイプを変更\"　＞　\"GPU\"　を選択して下さい。\n",
        "\n",
        "変更できたら、下の【②】のセルを実行して下さい。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iD9-Z2a81z3H",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル②】　\n",
        "#@markdown - ランタイムがGPUであることの確認\n",
        "#@markdown - Tensorflowのバージョンを 2.x に変更\n",
        "#@markdown - 効果音を[効果音ラボ](https://soundeffect-lab.info/)様よりダウンロード\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "if not exec_dict or '1' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "exec_dict['2'] = True\n",
        "\n",
        "! echo --------------\n",
        "! echo 【A】 ランタイムをGPUに変更\n",
        "! echo --------------\n",
        "\n",
        "! nvcc --version\n",
        "! nvidia-smi\n",
        "\n",
        "! echo --------------\n",
        "! echo 【B】 Tensorflowのバージョンを 2.x に変更\n",
        "! echo --------------\n",
        "\n",
        "%tensorflow_version 2.x\n",
        "%tensorflow_version\n",
        "\n",
        "! echo --------------\n",
        "! echo 【D】 効果音をダウンロード\n",
        "! echo --------------\n",
        "\n",
        "! wget --no-check-certificate -c \"https://soundeffect-lab.info/sound/anime/mp3/sceneswitch1.mp3\"\n",
        "\n",
        "from IPython.display import Audio, display\n",
        "def play_sound():\n",
        "    try:\n",
        "        display(Audio(\"sceneswitch1.mp3\", autoplay=True))\n",
        "    except:\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　効果音が再生できませんでした\")\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wnCvO_BM15Xu"
      },
      "source": [
        "**【OK】**\n",
        "\n",
        "下記のように表示されて、最後に音が鳴ったら成功です。\n",
        "※1.00.02でtensorflowの採用バージョンが2.xになりました。下記表示とちょっと変わってます\n",
        "\n",
        "![GPU切り替え失敗](https://drive.google.com/uc?export=view&id=1WK0Oo3qQESB8hVlkvyWfsq17LUn3N308)\n",
        "\n",
        "---\n",
        "\n",
        "**【NG】**\n",
        "\n",
        "下記のように表示されていたら、ランタイムの変更に失敗しているので、導入編を再度確認して、ランタイムを変更してください。\n",
        "\n",
        "![GPU変更成功](https://drive.google.com/uc?export=view&id=1E230eOWMctbD2F7qTvn_fR-3gBRQQ_uQ)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Oeyvm-Bq19kp"
      },
      "source": [
        "## **③　コード準備**\n",
        "\n",
        "MMD自動トレースコードをColab上に構築します。\n",
        "\n",
        "下の【③】のセルを実行してください。たくさんメッセージが出ます。\n",
        "\n",
        "【②】でDLした音が鳴ったら終了です。\n",
        "\n",
        "5行くらいエラーが最後に出ますが、リップトレースには影響がありませんので、そのまま進めていただいてOKです。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "w6PaKgyZ2BV3",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル③】　コード準備実行\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "if not exec_dict or '1' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "else:\n",
        "    import shutil\n",
        "    \n",
        "    if os.path.exists('./segmentation-kit-mmd'):\n",
        "        shutil.rmtree('./segmentation-kit-mmd')\n",
        "\n",
        "    # MMD自動トレースキットバージョンタグ（リップ）\n",
        "    ver_tag = \"ver1.00.03\"\n",
        "    # ver_tag = \"work_1.00\"\n",
        "\n",
        "    ! git clone  --depth 1 -b \"$ver_tag\" \"https://github.com/miu200521358/segmentation-kit-mmd.git\"\n",
        "\n",
        "    # 強制pipインストール\n",
        "    ! pip install --upgrade --force-reinstall -r \"segmentation-kit-mmd/requirements.txt\"\n",
        "\n",
        "    # 最新版Julius\n",
        "    if os.path.exists('./julius'):\n",
        "        shutil.rmtree('./julius')\n",
        "\n",
        "    ! sudo apt-get install build-essential zlib1g-dev libsdl2-dev libasound2-dev\n",
        "    ! git clone https://github.com/julius-speech/julius.git\n",
        "    ! cd julius && ./configure --enable-words-int && make -j4\n",
        "\n",
        "    ! sudo apt install git-lfs\n",
        "    ! cd ./julius/ && git clone https://github.com/julius-speech/dictation-kit.git\n",
        "\n",
        "    # # 入れ直し\n",
        "    # ! pip uninstall -y ffmpeg ffmpeg-python\n",
        "    # ! pip install ffmpeg ffmpeg-python\n",
        "\n",
        "    # %tensorflow_version 1.x\n",
        "\n",
        "    ! pip install spleeter==2.2.2\n",
        "    # quaternion\n",
        "    ! pip install numpy-quaternion==2020.11.2.17.0.49\n",
        "    # for bezier\n",
        "    ! pip install bezier==2020.5.19\n",
        "    ! pip install numba==0.48.0\n",
        "\n",
        "    exec_dict['3'] = True\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　コードの構築が完了しました。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f0Xo9-UN4pgK"
      },
      "source": [
        "## **④　入力音声アップロード**"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "z_hlyqAG4wHl"
      },
      "source": [
        "処理したい音声ファイルを、準備してください。\n",
        "\n",
        " - ファイル名は **半角英数字のみ** にしてください。opencvは2バイト文字を読み込めません。\n",
        " - ファイルは、wavファイルとmp3ファイルに対応しています。\n",
        " - 人間の声の他、楽曲としての音が入っていても問題ありません。（人の声のみ抜き出します）\n",
        " - ボカロ系の声は認識率が若干落ちます。\n",
        " - Googleドライブの **autotrace** フォルダ 直下に置いてください。\n",
        " - **マウント後のGooleドライブ上のファイルの上書きや更新は正しく認識されません。** 新しいファイルは新規の名前でアップロードしてから処理して下さい。\n",
        " - 入力するのは、ファイル名（拡張子含む）のみです。\n",
        " - 下の【④】のセルを実行して下さい。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "Yp74YAiS4vBH"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル④】　入力音声ファイルアップロード\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "\n",
        "#@markdown 解析対象となる音声のファイルの名前を入力して、セルを実行してください。\n",
        "\n",
        "input_audio_name = \"input.wav\"  #@param {type: \"string\"}\n",
        "\n",
        "if not exec_dict or '1' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "exec_dict['4'] = True\n",
        "\n",
        "input_audio_path = f\"{base_path}/{input_audio_name}\"\n",
        "\n",
        "if not os.path.exists(input_audio_path):\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　autotrace 直下に 指定音声 が見つかりませんでした。\")\n",
        "    print(\"■　ファイルパス: \" + input_audio_path)\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "else:\n",
        "    ! cp \"$input_audio_path\" .\n",
        "\n",
        "    input_audio_path = f\"/content/{input_audio_name}\"\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　入力音声 の設定が完了しました。\")\n",
        "    print(\"■　ファイルパス: \" + input_audio_path)\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0IgFAyl06IMB"
      },
      "source": [
        "## **⑤　MMD自動トレース（リップ）実行**"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FNO9kZxE6NhX"
      },
      "source": [
        "MMD自動トレースは音声分離・小節指定・モーション出力に分けて実行していただきます。\n",
        "\n",
        "下の【⑤-A】のセルを実行してください。\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ViHqL3GgAX4D"
      },
      "source": [
        "### ⑤-A　音声分離"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "k0SzyXxc6awB"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑤-A】　音声分離\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "import shutil\n",
        "\n",
        "if not exec_dict or '1' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '4' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル④が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "else:\n",
        "    if os.path.exists('/content/output'):\n",
        "        shutil.rmtree('/content/output')\n",
        "\n",
        "    import datetime\n",
        "    process_img_dir_name = \"{0}_{1:%Y%m%d_%H%M%S}\".format(os.path.basename(input_audio_path).replace('.', '_'), datetime.datetime.now())\n",
        "    process_img_dir_path = os.path.join('/content/output', process_img_dir_name)\n",
        "    os.makedirs(process_img_dir_path, exist_ok=True)\n",
        "\n",
        "    ! cd segmentation-kit-mmd/ && python executor.py --audio-file \"$input_audio_path\" --parent-dir \"$process_img_dir_path\" --process vocals --verbose 20 --log-mode 0\n",
        "\n",
        "    drive_dir_path = os.path.join(base_path, process_img_dir_name)\n",
        "\n",
        "    # mp4に変換\n",
        "    bbox_file_path = f\"{process_img_dir_path}/vocals.wav\"\n",
        "\n",
        "    import os\n",
        "    os.makedirs(drive_dir_path, exist_ok=True)\n",
        "\n",
        "    ! cp -f  \"$bbox_file_path\" \"$drive_dir_path\"\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　「vocals.wav」のGoogleドライブへのコピーが完了しました。\")\n",
        "    print(\"■　ファイルパス: \" + drive_dir_path + \"/vocals.wav\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    exec_dict['5-A'] = True\n",
        "\n",
        "    play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HDj1c6DkASzI"
      },
      "source": [
        "### ⑤-B　小節指定"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UJF9MusIAjtt"
      },
      "source": [
        "分離した声のみのwavデータを、`autotrace` の **「音声ファイル名+実行年月日のサブフォルダ」** に `vocals.wav` というファイル名で配置しているので、それをローカルにダウンロードしてください。\n",
        "\n",
        "[Audacity](https://forest.watch.impress.co.jp/library/software/audacity/) や [SoundEngine](https://forest.watch.impress.co.jp/library/software/soundengine/) など、音声が波形で見れて、ミリ秒まで確認出来るソフトでwavファイルを開いてください。\n",
        "\n",
        "（以下、Audacityで説明します）"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pmtZdqoABlxA"
      },
      "source": [
        "wavファイルのどの範囲が、歌詞のどの位置に相当するのかを指定していきます。\n",
        "\n",
        " - 歌詞ファイルは、ローカルに半角英数字のファイル名で作成してください。\n",
        "  - 文字コードは、Shift-JISもしくはUTF-8が処理可能なので、大抵のエディタだとそのままいけると思います。\n",
        " - 歌詞は全角ひらがな or 全角カタカナにしてください。\n",
        " - 英語などは日本語発音で適当に指定してください。\n",
        " - ひとつのブロックは、大体2～3小節くらいを目安にしてください。\n",
        " - 長く指定すると、一度判定がズレた時に、ずっとリップがズレるようになります。\n",
        " - 小節の区切りに空行を入れてください。\n",
        " - 歌詞の上の行に、<開始時間(ミリ秒3桁まで)>-<終了時間(ミリ秒3桁まで)>を指定してください。\n",
        " - 開始時間と終了時間は、出来るだけ発声の切れ目（空白を入れない）で指定してください。\n",
        " - 長音は、伸びている箇所だけ別に分離した方が綺麗に取れます。\n",
        "\n",
        "![音声位置](https://drive.google.com/uc?export=view&id=11ZTCGIRW2Whz3oO6CVRuydnSnKcYVs5f)\n",
        "\n",
        "**例**\n",
        "\n",
        "シザーハンズ 作曲: [Nem様](https://www.nicovideo.jp/watch/sm8901412) 歌: [ASK様](https://www.nicovideo.jp/watch/sm12835798)\n",
        "\n",
        "```\n",
        "3:31.380-3:32.445\n",
        "もうにどとー\n",
        "\n",
        "3:32.440-3:33.285\n",
        "とー\n",
        "\n",
        "3:33.368-3:35.650\n",
        "きずつけなーい\n",
        "\n",
        "3:35.720-3:40.225\n",
        "このては　このては　きみのそのほほに\n",
        "\n",
        "3:40.669-3:44.726\n",
        "いまならばふれられるきがすーる\n",
        "\n",
        "3:44.915-3:49.508\n",
        "もういちど　もういちど　いつかあえたならばー\n",
        "\n",
        "3:49.845-3:54.107\n",
        "あーああああー\n",
        "```\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WZle_gqTvfCK",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑤-B】　歌詞ファイル作成タイマー\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "\n",
        "#@markdown 歌詞ファイルを作成する際に、一定時間Colabを触らない時間が出来るかと思います。\n",
        "\n",
        "#@markdown 20分ほど触ってないと警告が出てしまいます。\n",
        "\n",
        "#@markdown こちらのセルを実行すると、任意分数のタイマーとなりますので、警告が出なくなります。\n",
        "\n",
        "timer_minutes = 10  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown 「Ctrl+M+I」のキーボードショートカットで、タイマーを途中でストップさせる事が出来ます。\n",
        "\n",
        "from time import sleep\n",
        "from tqdm import tqdm\n",
        "\n",
        "try:\n",
        "    for _ in tqdm(range(timer_minutes * 60)):\n",
        "        sleep(1)\n",
        "except:\n",
        "    print(\"\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** INFO **\")\n",
        "    print(\"■　タイマーを中断しました。\")\n",
        "    print(\"■　次のセルを実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    \n",
        "play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DpTWqzwMHKX0"
      },
      "source": [
        "### ⑤-C　歌詞ファイルアップロード"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VuWJbx5mFojE",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑤-C】　歌詞ファイルアップロード\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "\n",
        "#@markdown 歌詞ファイルを `autotrace` フォルダ直下にアップロードして、ファイル名を指定してください。\n",
        "\n",
        "#@markdown 置いた直後はファイルを認識できません。１分ほど待ってからセルを実行してください。\n",
        "\n",
        "input_lyrics_name = \"lyrics.txt\"  #@param {type: \"string\"}\n",
        "\n",
        "if not exec_dict or '1' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '4' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル④が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '5-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑤-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    \n",
        "else:\n",
        "    exec_dict['5-C'] = True\n",
        "\n",
        "    input_lyrics_path = f\"{base_path}/{input_lyrics_name}\"\n",
        "\n",
        "    if not os.path.exists(input_lyrics_path):\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　** ERROR **\")\n",
        "        print(\"■　autotrace 直下に 指定歌詞ファイル が見つかりませんでした。\")\n",
        "        print(\"■　ファイルパス: \" + input_lyrics_path)\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "    else:\n",
        "        ! cp \"$input_lyrics_path\" .\n",
        "\n",
        "        input_lyrics_path = f\"/content/{input_lyrics_name}\"\n",
        "\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　** OK **\")\n",
        "        print(\"■　歌詞ファイル の設定が完了しました。\")\n",
        "        print(\"■　ファイルパス: \" + input_lyrics_path)\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zGiE4EEOHQod"
      },
      "source": [
        "### ⑤-D　リップモーション作成"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9P5z3VkjHHaF",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑤-D】　リップモーション作成\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 間引き率を指定して、セルを実行してください。\n",
        "\n",
        "#@markdown **間引き率**　（プルダウンで選択できます）\n",
        "\n",
        "threshold = 0 #@param [0, 0.1, 0.2, 0.3, 1] {allow-input: true}\n",
        "\n",
        "#@markdown 間引き率０(ビブラートが入ります。代わりにほぼ全打ちになります。)\n",
        "\n",
        "#@markdown ![音声位置](https://drive.google.com/uc?export=view&id=1ZuxOWFaQC_nqMnq-fAEeYIvrEAwFZXHB)\n",
        "\n",
        "#@markdown 間引き率１(台形もしくは三角形のモーフ変化。調整前提用)\n",
        "\n",
        "#@markdown ![音声位置](https://drive.google.com/uc?export=view&id=1HS7fWOWPHuKmmRAK_M-eVW0deD6f5Y0-)\n",
        "\n",
        "import shutil\n",
        "\n",
        "if not exec_dict or '1' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '4' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル④が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '5-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑤-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '5-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑤-Cが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "else:\n",
        "    ! cd segmentation-kit-mmd/ && python executor.py --audio-dir \"$process_img_dir_path\" --lyrics-file \"$input_lyrics_path\" --process lip --threshold \"$threshold\" --verbose 20 --log-mode 0\n",
        "\n",
        "    # 日本語対策でpythonコピー\n",
        "    output_name = os.path.basename(input_audio_name).replace('.', '_')\n",
        "    output_path = os.path.join(base_path, process_img_dir_name)\n",
        "\n",
        "    import shutil\n",
        "    import glob\n",
        "    for vmd_path in glob.glob(os.path.join(process_img_dir_path, \"*.vmd\")):\n",
        "        out_vmd_path = os.path.join(drive_dir_path, os.path.basename(vmd_path))\n",
        "        shutil.copy(vmd_path, out_vmd_path)\n",
        "\n",
        "    for exo_path in glob.glob(os.path.join(process_img_dir_path, \"*.exo\")):\n",
        "        out_exo_path = os.path.join(drive_dir_path, os.path.basename(exo_path))\n",
        "        shutil.copy(exo_path, out_exo_path)\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　「vmdファイル」「exoファイル」のGoogleドライブへのコピーが完了しました。\")\n",
        "    print(\"■　ファイルパス: \" + drive_dir_path)\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    exec_dict['5-D'] = True\n",
        "\n",
        "    play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eh8FTXzfacXn"
      },
      "source": [
        "# 自動トレース後の作業"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Avi7Y9Mxbi31"
      },
      "source": [
        "## ①　GoogleドライブにVMD・EXOが出力されない場合"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-v0Vgu5Wblbu"
      },
      "source": [
        " - **ERROR**　**CRITICAL**　というメッセージが出ていないか確認してください。\n",
        " - メッセージが出ていない場合、処理出力フォルダにVMDファイルが出力されているか確認してください。\n",
        "   1. 画面左のフォルダーボタンをクリックしてください。\n",
        "\n",
        " ![フォルダーボタン](https://drive.google.com/uc?export=view&id=1AoTQjFHaz2uY4jGJttmVRkWk2nct2kb3)\n",
        "\n",
        "   2. `output/<音声ファイル名>_<実行年月日>_<実行時分秒>` フォルダの下にvmdファイルが出来ているか確認してください。\n",
        "\n",
        " ![motionフォルダ](https://drive.google.com/uc?export=view&id=1gyJnARopn8Qpwg2HSD3VwnYLzxoPqY56)\n",
        "\n",
        " ![motionフォルダ](https://drive.google.com/uc?export=view&id=1AVY6rPpufDemTpdeCAHWG3a6lVw3bRCS)\n",
        "\n",
        "     - VMDファイルがある場合、それをダウンロードしてください。\n",
        "        - ファイルを選択して右クリックすることで、メニューが表示されます。\n",
        "     - VMDファイルがない場合、どこかでエラーが発生しています。\n",
        "     - エラーの原因が分からない場合は、ノートブックを共有してください。\n",
        "       - 共有方法は、「[準備編](https://colab.research.google.com/github/miu200521358/motion_trace_colab/blob/master/AutoTraceIntroduction.ipynb)」を確認してください。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yz7-T0u6c0UN"
      },
      "source": [
        "## ②　リップがズレていて修正したい場合\n",
        "\n",
        " - 音節の前後に空白が入ってないか\n",
        " - 音が始まった後に区切ってないか\n",
        " - 長音でズレている場合、長音前後でさらに区切る\n",
        "\n",
        "修正した歌詞テキストファイルは、**先ほどとは別のファイル名** で、`autotrace` フォルダにアップロードして、`⑤-C` からやり直してください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_v5F77SPe-oe"
      },
      "source": [
        "## ③　リップの強弱を見ながら修正したい\n",
        "\n",
        "[Face And Lips](https://sites.google.com/site/moggproject/home) でモーフ毎の強弱が確認できます。\n",
        "\n",
        "※「Face And Lips」で出力したVMDデータは、VMDサイジング等他のツールとの相性がちょっと悪いので、一度MMDで読み込んで、別名保存した後のVMDデータでサイジング等を行ってください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Q0tf-6tEdwpO"
      },
      "source": [
        "## ④　最初からやり直したい場合\n",
        "\n",
        "1. メニューの「ランタイム」＞「ランタイムを出荷状態にリセット」＞「はい」をクリックしてください。\n",
        "\n",
        " ![リセット](https://drive.google.com/uc?export=view&id=1Eyi6OLpndFo63tyJsMtukIiL9p4wqBJs)\n",
        "\n",
        "2. メニュー右上の「再接続」をクリックしてください。\n",
        "\n",
        " ![再接続](https://drive.google.com/uc?export=view&id=1h7jF222tU4ZQz_jIMeDKYb9CNIbHTN1k)\n",
        "\n",
        "3. 緑のチェックマークがついたらリセット完了です。\n",
        "\n",
        " ![リセット完了](https://drive.google.com/uc?export=view&id=1FXq971EddklGtHMHpm_vQM0MtRvQrJ-y)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RKIFbg3uRJ6H"
      },
      "source": [
        "# ライセンス・クレジット"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HVPa8T5RRQr-"
      },
      "source": [
        "MMD自動トレースリップ版の結果を公開・配布する場合は、必ずライセンスのご確認をお願い致します。音声分離だけの場合も同様にご確認ください。\n",
        "\n",
        "[MMD自動トレースリップ版 ライセンス・クレジット](https://github.com/miu200521358/segmentation-kit-mmd/wiki/MMD自動トレースリップ版-ライセンス・クレジット)"
      ]
    }
  ]
}